use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use indoc::indoc;
use clap::Parser;
use anyhow::{Result, anyhow};

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    name: String,

    // #[arg(short, long)]
    // about: String,
}

fn main() -> Result<()> {
    let args = Args::parse();
    let base_path = PathBuf::from(&args.name);
    fs::create_dir(&base_path).map_err(|err| anyhow!("Cannot create directory {}, {}", &args.name, err))?;
    let src_path = base_path.clone().join("src");
    fs::create_dir(&src_path).map_err(|err| anyhow!("Cannot create directory {}, {}", "src", err))?;
    let out_path = base_path.clone().join("out");
    fs::create_dir(&out_path).map_err(|err| anyhow!("Cannot create directory {}, {}", "out", err))?;

    let just_txt = indoc! {"
        build:
            sdcc src/main.c -o out/main.ihx

        hex: build
            packihx out/main.ihx > out/main.hex

        burn: hex
            stcflash out/main.hex --port /dev/ttyUSB0
    "};
    let cmake_path = base_path.join("justfile");
    let file_cmake = File::create(cmake_path).map_err(|err| anyhow!("Cannot create CMakeLists.txt! {}", err))?;
    let mut cmake_buf_writer = std::io::BufWriter::new(file_cmake);
    let _ = cmake_buf_writer.write_all(just_txt.as_bytes());

    let main_c_str = indoc! {"
        #include <mcs51/8051.h>

        #define uchar unsigned char
        #define uint  unsigned int

        #define LED1 P1_0
        #define BLINK_INTERVAL 20

        uchar num = 0;

        // 每秒闪烁一次
        void T0_time(void) __interrupt(1) {
            TH0 = (65536 - 45872) / 256;
            TL0 = (65536 - 45872) % 256;
            num++;
            if (num == BLINK_INTERVAL) {
                num = 0;
                LED1 = !LED1;
            }
        }

        void init(void) {
            TMOD = 0x01; // 定时器0工作于方式1：16位定时器/计数器
            TH0 = (65536 - 45872) / 256; // 给寄存器0装初始值
            TL0 = (65536 - 45872) % 256;
            EA = 1;  // IE.EA：全局中断允许位
            ET0 = 1; // IE.ET0： 定时器/计数器0允许中断
            TR0 = 1; // TCON.TR0：启动定时器0
        }

        void main(void) {
            init();
            while (1);
        }"};

    let main_c_path = src_path.join("main.c");
    let file_main = File::create(main_c_path).map_err(|err| anyhow!("Cannot create main.cc! {}", err))?;
    let mut main_buf_writer = std::io::BufWriter::new(file_main);
    let _ = main_buf_writer.write_all(main_c_str.as_bytes());
    Ok(())
}
